#pragma once

#ifndef _I_DROPLET_SIM
#define _I_DROPLET_SIM

#include <btBulletDynamicsCommon.h>

#include "DropletDataStructs.h"
#include "DropletSimGlobals.h"
#include "DropletTimeControl.h"
#include "IDroplet.h"

#include <vector>
#include <cstdio>
#include <cstdlib>
#include <utility>
#include <math.h>

class SimSetupData;	// Defined after IDropletSim

class IDropletSim
{
private :

	SimPhysicsData *simPhysics;
	SimSetupData *simSetupData;

	DS_RESULT initPhysics(void);
	DS_RESULT endPhysics(void);

	DS_RESULT initPhysicsObject(
		ObjectPhysicsData *objPhysics, btVector3 &origin);

	// Control and Update Functions
	void motionController(void);

protected :

	bool firstRun;
	std::vector<IDroplet *> droplets;

public :
	
	IDropletSim(void);
	virtual ~IDropletSim();

	virtual DS_RESULT AddCollisionShape(btCollisionShape *colShape, int *colShapeIndex);
	
	virtual DS_RESULT CreateFloor(
		int floorShapeIndex, 
		int wallXShapeIndex = -1, 
		int wallYShapeIndex = -1);

	virtual DS_RESULT AddDroplet(
		IDroplet *pDroplet, 
		std::pair<float, float>startPos,
		float startAngle);

	virtual DS_RESULT Init(const SimSetupData &setupData);
	virtual DS_RESULT Step(void);
	virtual DS_RESULT Cleanup(void);

	// Getters
	virtual DS_RESULT GetDropletPositions(std::vector<float *> *xyValues);
	virtual DS_RESULT GetDropletColors(std::vector<uint8_t *> *colors);


	/* NOTE : The Run() method should only be used if this program is
	 * compiled as an exectutable. The recommended use of this class is
	 * as part of the Droplet Library and so loop control should be part
	 * of whatever other program is using this library.
	 */
//	DS_RESULT Run(void);
};

class SimSetupData
{
private :

	int numRowTiles, numColTiles;
	float tileLength, dropletRadius;
	float fps, timestep;
	bool autoBuildBoundaryWalls;

	friend class IDropletSim;

public :
	SimSetupData(
		int numRowTiles,
		int numColTiles,
		float tileLength,
		float dropletRadius,
		float fps,
		bool autoBuildBoundaryWalls
	);

	SimSetupData(const SimSetupData& setupData);

};

#endif